package com.cowin.inf.controller;


import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.cowin.base.result.Result;
import com.cowin.base.result.ResultGenerator;
import com.cowin.inf.model.KyDeviceStateInfo;
import com.cowin.inf.model.KyLineState;
import com.cowin.inf.model.KyLineStateInfo;
import com.cowin.inf.model.vo.*;
import com.cowin.inf.service.KyLineStateInfoService;
import com.cowin.inf.service.KyLineStateService;
import com.cowin.inf.service.MonitorService;
import com.cowin.sys.model.TmBasLine;
import com.cowin.sys.model.TmBasUloc;
import com.cowin.sys.model.vo.IdNameVo;
import com.cowin.sys.service.*;
import com.cowin.utils.Arith;
import com.google.common.collect.ImmutableMap;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;

/**
 * Copyright (C), 1998-2019, 奇瑞信息
 *
 * @author : 于超
 * @Date: 2020/1/10 10:53
 * @Description:
 */
@Slf4j
@Api(value = "MonitorController", description = "监控数据控制器", tags = "MonitorController", consumes = "application/json")
@RestController
@RequestMapping("/production/monitor")
public class MonitorController {
    private static final String BETWEEN = "between";
    private static final String THRU = "thru";

    @Resource
    private TcSysCodeListService tcSysCodeListService;

    @Resource
    private TmOfmOrderService tmOfmOrderService;

    @Resource
    private TmBasMaterialRelationService tmBasMaterialRelationService;
    @Resource
    private TmVhcVehicleService tmVhcVehicleService;
    @Resource
    private TmBasLineService tmBasLineService;
    @Resource
    private TmBasUlocService tmBasUlocService;
    @Resource
    private TmVhcVehicleMovementService tmVhcVehicleMovementService;
    @Resource
    private TmBasWorkshopService tmBasWorkshopService;
    @Resource
    private KyLineStateService kyLineStateService;
    @Resource
    private KyLineStateInfoService kyLineStateInfoService;

    @Resource
    private MonitorService monitorService;

    private final String[] hz = {"HZ11AS01"};
    private final String[] tz = {"TZ11AS01"};
    private final String[] zz = {"ZZ11AS01"};
    private final Map<String, String[]> workShopMap = ImmutableMap.of("HZ11", hz, "TZ11", tz, "ZZ11", zz);
    private final Map<String, String> pointMap = ImmutableMap.of("HZ11AS01", "FN220", "TZ11AS01", "OP014", "ZZ11AS01", "Z100");

    private final long ND = 1000 * 24 * 60 * 60;
    private final long NH = 1000 * 60 * 60;
    private final long NM =1000 * 60;

    @ApiOperation("车间生产监控")
    @GetMapping("/line")
    public Result get() {
        //获取车间点位关系
        List<IdNameVo> tmBasUlocId = tcSysCodeListService.getTmBasUlocId();
        //点位之间车身数量
        List<Integer> betweenPointList = new ArrayList<>();
        //点位一天经过数量
        List<Integer> pointThrulist = new ArrayList<>();
        //获取点位之间车辆信息
        for (int i = 0; i < tmBasUlocId.size(); i++) {
            //查询两点之间车辆信息
            if (i == 0 || i == tmBasUlocId.size()) {
                betweenPointList.add(monitorService.findVehicleBetweenPoint(tmBasUlocId.get(i).getId(), tmBasUlocId.get(i).getId()).size());
            } else {
                betweenPointList.add(monitorService.findVehicleBetweenPoint(tmBasUlocId.get(i - 1).getId(), tmBasUlocId.get(i).getId()).size());
            }
            //查询点位当天经过车辆信息
            pointThrulist.add(monitorService.findVehiclePointThru(tmBasUlocId.get(i).getId()).size());
        }
        List<String> lockedUpCountList = tmOfmOrderService.lockedUpCount();
        betweenPointList.set(0, lockedUpCountList.size());
        Map<String, List> map = new HashMap<>(2);
        map.put("between", betweenPointList);
        map.put("thru", pointThrulist);
        return ResultGenerator.genSuccessResult(map);
    }

    @ApiOperation("车间过点车辆具体信息")
    @GetMapping("/line/{type}/{column}/{index}")
    public Result getVehicleInfo(@PathVariable String type, @PathVariable String column, @PathVariable Integer index) {
        //获取车间点位关系
        List<IdNameVo> tmBasUlocId = tcSysCodeListService.getTmBasUlocId();
        if (BETWEEN.equals(type)) {
            //查询两点之间车辆信息
            if (index == 0) {
                //获取锁定的订单的整车物料号
                List<String> lockedUpCountVinList = tmOfmOrderService.lockedUpCount();
                //查询整车物料号 油漆车身物料号 白车身物料号 车型 数量
                List<MaterialTypeCountVo> list = new ArrayList<>();
                if (!CollectionUtils.isEmpty(lockedUpCountVinList)) {
                    list = tmBasMaterialRelationService.findBsPsTypeByVinOrId(lockedUpCountVinList, column, "VIN");
                }
                return ResultGenerator.genSuccessResult(list);
            } else {
                List<String> vehicleBetweenPoint = monitorService.findVehicleBetweenPoint(tmBasUlocId.get(index - 1).getId(), tmBasUlocId.get(index).getId());
                List<MaterialTypeCountVo> list = new ArrayList<>();
                if (!CollectionUtils.isEmpty(vehicleBetweenPoint)) {
                    list = tmBasMaterialRelationService.findBsPsTypeByVinOrId(vehicleBetweenPoint, column, "TM_VHC_VEHICLE_ID");
                }
                return ResultGenerator.genSuccessResult(list);
            }

        } else if (THRU.equals(type)) {
            //查询过点车辆信息
            List<String> vehiclePointThru = monitorService.findVehiclePointThru(tmBasUlocId.get(index).getId());
            //查询整车物料号 油漆车身物料号 白车身物料号 车型 数量
            List<MaterialTypeCountVo> list = new ArrayList<>();
            if (!CollectionUtils.isEmpty(vehiclePointThru)) {
                list = tmBasMaterialRelationService.findBsPsTypeByVinOrId(vehiclePointThru, column, "TM_VHC_VEHICLE_ID");
            }
            return ResultGenerator.genSuccessResult(list);
        }
        return ResultGenerator.genFailResult("类型不正确");
    }

    @ApiOperation("jph小时推移")
    @PostMapping("/jph")
    public Result jphMonitor(@RequestBody JphVo jphVo) {
        List<JphWorkShop> jphWorkShops = new ArrayList<>();
        if (!StringUtils.isNotBlank(jphVo.getWorkShopNo())) {
            for (String key : workShopMap.keySet()) {
                JphWorkShop jphWorkShop = new JphWorkShop();
                List<JphLine> jphLineList = new ArrayList<>();
                String[] strings = workShopMap.get(key);
                for (String linNo : strings) {
                    JphLine jphLine = new JphLine();
                    TmBasLine lineInfoByLineNo = tmBasLineService.getLineInfoByLineNo(linNo);
                    jphLine.setJph(lineInfoByLineNo.getLineJph() == null ? "0" : lineInfoByLineNo.getLineJph());
                    jphLine.setName(lineInfoByLineNo.getLineNameC());
                    String ulocNo = pointMap.get(linNo);
                    //工位编码查询 工位信息
                    TmBasUloc ulocByUlocNo = tmBasUlocService.getUlocByUlocNo(ulocNo);
                    //根据工位Id 时间查询 产量
                    List<JphHHVo> realityJph = tmVhcVehicleMovementService.getRealityJph(ulocByUlocNo.getTmBasUlocId().toString(), jphVo.getStartTime());
                    jphLine.setRealityJph(realityJph);
                    jphLineList.add(jphLine);
                }
                jphWorkShop.setJphLineList(jphLineList);
                jphWorkShops.add(jphWorkShop);
            }
        } else {
            JphWorkShop jphWorkShop = new JphWorkShop();
            String[] strings = workShopMap.get(jphVo.getWorkShopNo());
            List<JphLine> jphLineList = new ArrayList<>();
            for (String linNo : strings) {
                JphLine jphLine = new JphLine();
                TmBasLine lineInfoByLineNo = tmBasLineService.getLineInfoByLineNo(linNo);
                jphLine.setName(lineInfoByLineNo.getLineNameC());
                jphLine.setJph(lineInfoByLineNo.getLineJph() == null ? "0" : lineInfoByLineNo.getLineJph());
                String ulocNo = pointMap.get(linNo);
                //工位编码查询 工位信息
                TmBasUloc ulocByUlocNo = tmBasUlocService.getUlocByUlocNo(ulocNo);
                //根据工位Id 时间查询 产量
                List<JphHHVo> realityJph = tmVhcVehicleMovementService.getRealityJph(ulocByUlocNo.getTmBasUlocId().toString(), jphVo.getStartTime());
                jphLine.setRealityJph(realityJph);
                jphLineList.add(jphLine);
            }
            jphWorkShop.setJphLineList(jphLineList);
            jphWorkShops.add(jphWorkShop);
        }

        return ResultGenerator.genSuccessResult(jphWorkShops);
    }

    @ApiOperation("生产线监控")
    @GetMapping("/workShop")
    public Result workShopMonitor() {
        List<WorkMonitorShopVo> workShopMonitorInfo = tmBasWorkshopService.getWorkShopMonitorInfo();
        Date date = new Date();
        String today = DateUtil.today();
        Date beginDate = DateUtil.parse(today + " 08:00:00");

        int hour = DateUtil.hour(date, true);
        //8.00---8.00 系统当前时间 大于八点 查今天  小于八点 昨天
        int type = 1;
        if (hour < 8) {
            type = 0;
            beginDate = DateUtil.offsetDay(beginDate, -1);
        }

        for (int i = 0; i < workShopMonitorInfo.size(); i++) {
            WorkMonitorShopVo workMonitorShopVo = workShopMonitorInfo.get(i);
            String workshopNo = workMonitorShopVo.getWorkshopNo();
            List<LineMonitorVo> lineList = workMonitorShopVo.getLineList();
            //查询日运行累计
            Integer autoTimeTotal = 0;
            Integer faultTimeTotal = 0;
            for (int j = 0; j < lineList.size(); j++) {
                LineMonitorVo lineMonitorVo = lineList.get(j);
                String lineNo = lineMonitorVo.getLineNo();
                //查询产线状态
                KyLineState lineState = kyLineStateService.getLineState(workshopNo, lineNo);
                //查询产线开动率
                List<KyLineStateInfo> autoList = kyLineStateInfoService.getLine8to8AutoTime(workshopNo, lineNo, type, "AUTO");
                List<KyLineStateInfo> standbyList = kyLineStateInfoService.getLine8to8AutoTime(workshopNo, lineNo, type, "STANDBY");
                List<KyLineStateInfo> faultList = kyLineStateInfoService.getLine8to8AutoTime(workshopNo, lineNo, type, "FAULT");
                Integer autoTime = 0;
                Integer standByTime = 0;
                Integer faultTime = 0;
                if (autoList.size() > 0) {
                    autoTime = runMin(autoList, beginDate);
                }
                if (standbyList.size() > 0) {
                    standByTime = runMin(standbyList, beginDate);
                }
                if(faultList.size()>0){
                    faultTime=runMin(faultList, beginDate);
                }

                if (lineState != null) {
                    String status = lineState.getStatus();
                    lineMonitorVo.setLineState(status);
                    //加上没有记录到info表的时间
                    long autoOrStandByMinNow = DateUtil.between(lineState.getNodeTime(), date, DateUnit.MINUTE);
                    if ("AUTO".equals(status)) {
                        autoTime += Integer.parseInt(autoOrStandByMinNow + "");
                    } else if ("STANDBY".equals(status)) {
                        standByTime += Integer.parseInt(autoOrStandByMinNow + "");
                    }else if("FAULT".equals(status)){
                        faultTime += Integer.parseInt(autoOrStandByMinNow + "");
                    }
                }
                //查看  开始到现在 总共多少分钟 减去休息
                long totalMin = DateUtil.between(date, beginDate, DateUnit.MINUTE);
                long denominator = totalMin - standByTime;
                double div = Arith.div(autoTime, denominator, 2);
                //插入可动率
                lineMonitorVo.setLineUptimeRate(div + "");
                autoTimeTotal+=autoTime;
                faultTimeTotal+=faultTime;
            }
            Map<String,String> map = new HashMap<>(2);
            map.put("auto",autoTimeTotal+"");
            map.put("fault",faultTimeTotal+"");
            workMonitorShopVo.setDayRunAccumulate(map);
        }
        return ResultGenerator.genSuccessResult(workShopMonitorInfo);
    }

    private int runMin( List<KyLineStateInfo> list, Date beginDate){
        int runMin =0;
        KyLineStateInfo kyLineStateInfo = list.get(0);
        Date startTime = kyLineStateInfo.getStartTime();
        long diff = startTime.getTime() - beginDate.getTime();
        long min = diff % ND % NH / NM;
        if (min < 0) {
            list.get(0).setStartTime(startTime);
            list.get(0).setDelay(list.get(0).getDelay() + Integer.parseInt(min + ""));
        }
        for (KyLineStateInfo standby : list) {
            runMin += standby.getDelay();
        }
        return runMin;
    }
}
